package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.system.dto.SysAllowedJoinCompanyUserDTO;
import com.nineclock.system.dto.SysApplyJoinCompanyUserDTO;
import com.nineclock.system.dto.SysChangeMainManagerDTO;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.mapper.*;
import com.nineclock.system.message.enums.MessageTypeEnum;
import com.nineclock.system.message.pojo.NcMessage;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SmsService;
import com.nineclock.system.service.SysCompanyService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class SysCompanyServiceImpl implements SysCompanyService {
    @Autowired
    SysCompanyMapper sysCompanyMapper;
    @Autowired
    OSS oss;
    @Autowired
    OssProperties ossProperties;
    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    SysRoleMapper roleMapper;
    @Autowired
    SysCompanyUserRoleMapper sysCompanyUserRoleMapper;
    @Autowired
    SmsService smsService;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    RocketMQTemplate rocketMQTemplate;

    @Override
    public SysCompanyDTO queryCompanyInfo() {
        //获取当前用户的企业信息
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);

        if (sysCompany == null) {
            throw new NcException(ResponseEnum.COMPANY_CONTACT_CONFIG_NOT_FOND);
        }
        SysCompanyDTO sysCompanyDTO = BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);
        return sysCompanyDTO;
    }

    @Override
    public String uploadCompanyLogo(MultipartFile file) throws IOException {
        //判断是否存在文件
        if (file == null) {
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }
        //判断文件后缀是否正确
        String fileType = file.getContentType();
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(fileType)) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }
        //判断文件大小
        long fileSize = file.getSize();
        if (fileSize > NcConstant.maxFileSize) {
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }
        //获取原始文件名(包含后缀)
        String fileName = file.getOriginalFilename();
        int index = fileName.lastIndexOf(".");
        String fileSuffix = fileName.substring(index);
        //获取唯一文件名+后缀
        String uuidName = UUIDUtils.getUUID() + fileSuffix;

        oss.putObject(ossProperties.getBucketName(), uuidName, file.getInputStream());

        String filePath = String.format(ossProperties.getHost(), ossProperties.getBucketName()) + uuidName;
        return filePath;
    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        if (sysCompanyDTO == null) {
            throw new NcException(ResponseEnum.MESSAGE_PARAMS_LOST);
        }
        //获取当前企业信息id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //获取到企业信息
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);
        if (sysCompany == null) {
            throw new NcException(ResponseEnum.COMPANY_CONTACT_CONFIG_NOT_FOND);
        }
        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setName(sysCompanyDTO.getName());

        System.out.println(sysCompany + "=========================");
        System.out.println(sysCompanyDTO + "--------------");
        sysCompanyMapper.updateById(sysCompany);


    }

    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //1. 健壮性判断
        if (sysChangeMainManagerDTO == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //2. 新管理员 是否存在
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        //校验企业id
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);//校验账号是否启用
        wrapper.eq(SysCompanyUser::getId, sysChangeMainManagerDTO.getUserId());//校验新管理员是否存在

        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectOne(wrapper);
        if (sysCompanyUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //3. 校验验证码是否正确


        Boolean flag = smsService.verifySmsCode(sysCompanyUser.getMobile(), SMSConstant.SMS_TYPE_CHANGE_MANAGER, sysChangeMainManagerDTO.getCode());
        if(!flag){
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }

//        String code = sysChangeMainManagerDTO.getCode();//从请求中拿出code
//        //从redis中取出code
//        Object redisCode = redisTemplate.boundValueOps(SMSConstant.SMS_TYPE_CHANGE_MANAGER + sysCompanyUser.getMobile()).get();
//        if (redisCode == null || !redisCode.equals(code)){
//            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
//        }
        //4. 删除原管理员与角色的关系， 添加新管理员的关系
        //获取主管理员  角色 id
        LambdaQueryWrapper<SysRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.eq(SysRole::getCompanyId,companyId);
        roleLambdaQueryWrapper.eq(SysRole::getRoleName,"ROLE_ADMIN_SYS");
        SysRole sysRole = roleMapper.selectOne(roleLambdaQueryWrapper);

        //删除原管理员关系

        LambdaQueryWrapper<SysCompanyUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUserRole::getRoleId,sysRole.getId());//获取当前用户的role关联表id
        queryWrapper.eq(SysCompanyUserRole::getCompanyId,companyId);//获取当前用户的企业id
        queryWrapper.eq(SysCompanyUserRole::getCompanyUserId,CurrentUserHolder.get().getCompanyUserId());//当前用户的用户表id
        sysCompanyUserRoleMapper.delete(queryWrapper);

        //插入新的管理员信息

        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyId(companyId);//将当前用户的企业id赋值
        companyUserRole.setCompanyUserId(sysChangeMainManagerDTO.getUserId());//将传递过来的用户信息赋值
        companyUserRole.setRoleId(sysRole.getId());//

        sysCompanyUserRoleMapper.insert(companyUserRole);


    }

    /**
     * 根据关键字查询企业信息
     * @param keyword  关键字
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(SysCompany::getName,keyword);

        List<SysCompany> sysCompanies = sysCompanyMapper.selectList(wrapper);

        if (sysCompanies == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        return BeanHelper.copyWithCollection(sysCompanies,SysCompanyDTO.class);
    }

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {
        //健壮性判断
        if(sysApplyJoinCompanyUserDTO == null){
            throw new NcException(ResponseEnum.MESSAGE_PARAMS_LOST);
        }
        //查询此用户是否存在
        SysUser sysUser = sysUserMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());
        if (sysUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //将填写的信息更新到user表中
        sysUser.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        sysUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysUser.setUpdateTime(new Date());
        sysUser.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());

        sysUserMapper.updateById(sysUser);

        //将user的信息增加到员工信息表中

        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setUserId(sysUser.getId());
        sysCompanyUser.setUserName(sysUser.getUsername());
        sysCompanyUser.setEnable((short)0); //没有审核通过加入企业，所以设置为 0
        sysCompanyUser.setTimeEntry(new Date());
        sysCompanyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());
        sysCompanyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysCompanyUser.setPost(sysApplyJoinCompanyUserDTO.getPost());
        sysCompanyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        sysCompanyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        sysCompanyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());
        sysCompanyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl());
        sysCompanyUser.setCreateTime(new Date());

        //查询系统主管理员
        SysCompanyUser currentAdmin = sysCompanyUserMapper.queryMainAdminCompanyUser(sysApplyJoinCompanyUserDTO.getCompanyId());

        sysCompanyUserMapper.insert(sysCompanyUser);

        NcMessage message = new NcMessage();
        message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType());
        message.setCreateTime(new Date());
        message.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId() + "");
        message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle());
        message.setContent(sysApplyJoinCompanyUserDTO.getUserName() + " 申请加入企业，请及时审批");
        message.setUseStatus(0);
        message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience());
        message.setTargets(Arrays.asList(currentAdmin.getMobile())); //主管理员的手机号码
        message.setApproveStatue(0);
        message.setApplyUserId(sysUser.getId());
        message.setApplyUsername(sysApplyJoinCompanyUserDTO.getUserName());
        message.setApproveUserId(currentAdmin.getUserId());
        message.setApproveUsername(currentAdmin.getUserName());


        rocketMQTemplate.convertAndSend("messagePushTopic",message);

    }

    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
        //健壮性判断
        if (sysAllowedJoinCompanyUserDTO == null){
            throw new NcException(ResponseEnum.MESSAGE_PARAMS_LOST);
        }
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getUserId,sysAllowedJoinCompanyUserDTO.getApplyUserId());

        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectById(wrapper);
        //更新信息
        //更新状态值
        sysCompanyUser.setEnable((short)(sysAllowedJoinCompanyUserDTO.getApproved() ? 1:  0));
        //更新状态信息
        sysCompanyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());
        sysCompanyUser.setUpdateTime(new Date());
        //更新
        sysCompanyUserMapper.updateById(sysCompanyUser);

        //todo
        //将审核结果推送给用户

        //2. 推送消息
        //2.1 推送消息 ， 消费方 只是用来更新mongo中的信息
        rocketMQTemplate.convertAndSend("sysAllowedJoinCompanyUserDTO", sysAllowedJoinCompanyUserDTO.getNotifyMsgId());
        //2.2 推送消息, 负责推送消息给申请人(只是使用原来的消费监听器)
        NcMessage message = new NcMessage();
        message.setMessageType(MessageTypeEnum.COMPANY_APPLY_PASS.getType()) ;
        message.setCreateTime(new Date());
        message.setCompanyId(CurrentUserHolder.get().getCompanyId() + "");
        message.setTitle(MessageTypeEnum.COMPANY_APPLY_PASS.getTitle());
        message.setContent("您加入企业的申请已通过!");
        message.setAudience(MessageTypeEnum.COMPANY_APPLY_PASS.getAudience());
        message.setApproveResult(sysAllowedJoinCompanyUserDTO.getRemark());
        message.setApplyUserId(sysAllowedJoinCompanyUserDTO.getApplyUserId());
        message.setApplyUsername(sysCompanyUser.getUserName());

        message.setApproveUserId(CurrentUserHolder.get().getId()); //审批 用户id
        message.setApplyUsername(CurrentUserHolder.get().getUsername());
        message.setTargets(Arrays.asList(sysCompanyUser.getMobile())); //申请人 手机号(作为别名 推送消息)

        rocketMQTemplate.convertAndSend("messagePushTopic", message);
    }

    /**
     * 根据系统用户id查询 企业列表
     * @param userId
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryCompanyListByUserId(Long userId) {
        if(userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<SysCompany> companyList = sysCompanyMapper.queryCompanyListByUserId(userId);
        if(CollectionUtil.isEmpty(companyList)){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        return BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
    }
}
